package com.kxyu.cash_drawer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class BytesUtil {
	public static String bytes2HexString(byte[] data) {
		StringBuilder buffer = new StringBuilder();
		byte[] arrayOfByte = data;
		int j = data.length;
		for (int i = 0; i < j; i++) {
			byte b = arrayOfByte[i];
			String hex = Integer.toHexString(b & 0xFF);
			if (hex.length() == 1) {
				buffer.append('0');
			}
			buffer.append(hex);
		}
		return buffer.toString().toUpperCase();
	}

	public static byte[] hexString2Bytes(String data) {
		byte[] result = new byte[(data.length() + 1) / 2];
		if ((data.length() & 0x1) == 1) {
			data = data + "0";
		}
		for (int i = 0; i < result.length; i++) {
			result[i] = ((byte) (hex2byte(data.charAt(i * 2 + 1)) | hex2byte(data
					.charAt(i * 2)) << 4));
		}
		return result;
	}
	

	public static byte hex2byte(char hex) {
		if ((hex <= 'f') && (hex >= 'a')) {
			return (byte) (hex - 'a' + 10);
		}
		if ((hex <= 'F') && (hex >= 'A')) {
			return (byte) (hex - 'A' + 10);
		}
		if ((hex <= '9') && (hex >= '0')) {
			return (byte) (hex - '0');
		}
		return 0;
	}

	public static byte[] subBytes(byte[] data, int offset, int len) {
		if ((offset < 0) || (data.length <= offset)) {
			return null;
		}
		if ((len < 0) || (data.length < offset + len)) {
			len = data.length - offset;
		}
		byte[] ret = new byte[len];

		System.arraycopy(data, offset, ret, 0, len);
		return ret;
	}

	public static byte[] getBytes(byte[] data, int offset, int len) {
		if ((offset < 0) || (data.length <= offset)) {
			return null;
		}
		byte[] ret = new byte[len];
		System.arraycopy(data, offset, ret, 0, len);
		return ret;
	}

	public static byte[] merage(byte[]... data) {
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
		try {
			byte[][] arrayOfByte = data;
			int j = data.length;
			for (int i = 0; i < j; i++) {
				byte[] d = arrayOfByte[i];
				if (d == null) {
					throw new IllegalArgumentException("");
				}
				buffer.write(d);
			}
			return buffer.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				buffer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static int bytesToInt(byte[] bytes) {
		if (bytes.length > 4) {
			return -1;
		}
		int lastIndex = bytes.length - 1;
		int result = 0;
		for (int i = 0; i < bytes.length; i++) {
			result |= (bytes[i] & 0xFF) << (lastIndex - i << 3);
		}
		return result;
	}

	public static int littleEndianBytesToInt(byte[] bytes) {
		if (bytes.length > 4) {
			return -1;
		}
		int result = 0;
		for (int i = 0; i < bytes.length; i++) {
			result |= (bytes[i] & 0xFF) << (i << 3);
		}
		return result;
	}

	public static byte[] intToBytes(int intValue) {
		byte[] bytes = new byte[4];
		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = ((byte) (intValue >> (3 - i << 3) & 0xFF));
		}
		return bytes;
	}

	public static byte[] intToLittleEndianBytes(int intValue) {
		byte[] bytes = new byte[4];
		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = ((byte) (intValue >> (i << 3) & 0xFF));
		}
		return bytes;
	}

	public static String bcd2Ascii(byte[] bcd) {
		if (bcd == null) {
			return "";
		}
		StringBuilder sb = new StringBuilder(bcd.length << 1);
		byte[] arrayOfByte = bcd;
		int j = bcd.length;
		for (int i = 0; i < j; i++) {
			byte ch = arrayOfByte[i];
			byte half = (byte) (ch >> 4);
			sb.append((char) (half + (half > 9 ? 55 : 48)));
			half = (byte) (ch & 0xF);
			sb.append((char) (half + (half > 9 ? 55 : 48)));
		}
		return sb.toString();
	}

	public static byte[] ascii2Bcd(String ascii) {
		if (ascii == null) {
			return null;
		}
		if ((ascii.length() & 0x1) == 1) {
			ascii = "0" + ascii;
		}
		byte[] asc = ascii.getBytes();
		byte[] bcd = new byte[ascii.length() >> 1];
		for (int i = 0; i < bcd.length; i++) {
			bcd[i] = ((byte) (hex2byte((char) asc[(2 * i)]) << 4 | hex2byte((char) asc[(2 * i + 1)])));
		}
		return bcd;
	}

	public static byte[] toBytes(String data, String charsetName) {
		try {
			return data.getBytes(charsetName);
		} catch (UnsupportedEncodingException e) {
		}
		return null;
	}

	public static byte[] toBytes(String data) {
		return toBytes(data, "ISO-8859-1");
	}

	public static byte[] toGBK(String data) {
		return toBytes(data, "GBK");
	}

	public static byte[] toGB2312(String data) {
		return toBytes(data, "GB2312");
	}

	public static byte[] toUtf8(String data) {
		return toBytes(data, "UTF-8");
	}

	public static String fromBytes(byte[] data, String charsetName) {
		try {
			return new String(data, charsetName);
		} catch (UnsupportedEncodingException e) {
		}
		return null;
	}

	public static String fromBytes(byte[] data) {
		return fromBytes(data, "ISO-8859-1");
	}

	public static String fromGBK(byte[] data) {
		return fromBytes(data, "GBK");
	}

	public static String fromGB2312(byte[] data) {
		return fromBytes(data, "GB2312");
	}

	public static String fromUtf8(byte[] data) {
		return fromBytes(data, "UTF-8");
	}

	/**
	 * @功能: BCD码转为10进制串(阿拉伯数据)
	 * @参数: BCD码
	 * @结果: 10进制串
	 */
	public static String bcd2Str(byte[] bytes) {
		StringBuffer temp = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; i++) {
			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
			temp.append((byte) (bytes[i] & 0x0f));
		}
		return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
				.toString().substring(1) : temp.toString();
	}

	/**
	 * @功能: 10进制串转为BCD码
	 * @参数: 10进制串
	 * @结果: BCD码
	 */
	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;
		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}
		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}
		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;
		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}
			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}
			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}
	
	/**
	 * @功能: 10进制串转为BCD码
	 * @参数: 10进制串
	 * @结果: BCD码
	 */
	public static byte[] str2BcdAppendF(String asc) {
		int len = asc.length();
		int mod = len % 2;
		if (mod != 0) {
			asc = asc + "F";
			len = asc.length();
		}
		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}
		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;
		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}
			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}
			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}
}
